package priv.yiyuan.example.inputstream;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @author YiYuan
 * @data 2025/8/13
 * @apoNote
 */
public class StreamUtils {

    /**
     * 将InputStream读取为字节数组
     *
     * @param inputStream 输入流
     * @return 字节数组
     * @throws IOException
     */
    public static byte[] readToByteArray(InputStream inputStream) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        byte[] data = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, bytesRead);
        }
        buffer.flush();
        return buffer.toByteArray();
    }

    /**
     * 将InputStream读取为字符串(UTF-8编码)
     *
     * @param inputStream 输入流
     * @return 字符串内容
     * @throws IOException
     */
    public static String readToString(InputStream inputStream) throws IOException {
        return new String(readToByteArray(inputStream), StandardCharsets.UTF_8);
    }

    /**
     * 将InputStream读取为字符串(指定编码)
     *
     * @param inputStream 输入流
     * @param charsetName 字符编码名称
     * @return 字符串内容
     * @throws IOException
     */
    public static String readToString(InputStream inputStream, String charsetName) throws IOException {
        return new String(readToByteArray(inputStream), charsetName);
    }

    /**
     * 使用Java 8 Stream API读取InputStream为字符串
     *
     * @param inputStream 输入流
     * @return 字符串内容
     */
    public static String readToStringWithStream(InputStream inputStream) {
        return new BufferedReader(new InputStreamReader(inputStream))
                .lines()
                .collect(Collectors.joining("\n"));
    }


    ///**
    // * 安全读取InputStream到字节数组(自动关闭流)
    // * @param inputStream 输入流
    // * @return 字节数组
    // * @throws IOException
    // */
    //public static byte[] readToByteArray(InputStream inputStream) throws IOException {
    //    try (InputStream is = inputStream;
    //         ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
    //
    //        byte[] data = new byte[4096];
    //        int bytesRead;
    //        while ((bytesRead = is.read(data, 0, data.length)) != -1) {
    //            buffer.write(data, 0, bytesRead);
    //        }
    //        return buffer.toByteArray();
    //    }
    //}

    ///**
    // * 安全读取InputStream到字符串(自动关闭流)
    // * @param inputStream 输入流
    // * @return 字符串内容
    // * @throws IOException
    // */
    //public static String readToString(InputStream inputStream) throws IOException {
    //    return new String(readToByteArray(inputStream), StandardCharsets.UTF_8);
    //}



    /**
     * 分块处理大文件流(避免内存溢出)
     * @param inputStream 输入流
     * @param chunkSize 每块大小(字节)
     * @param chunkConsumer 每块数据的处理器
     * @throws IOException
     */
    public static void processInChunks(InputStream inputStream,
                                       int chunkSize,
                                       Consumer<byte[]> chunkConsumer) throws IOException {
        try (InputStream is = inputStream) {
            byte[] buffer = new byte[chunkSize];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                if (bytesRead < chunkSize) {
                    // 最后一块可能不满
                    byte[] lastChunk = new byte[bytesRead];
                    System.arraycopy(buffer, 0, lastChunk, 0, bytesRead);
                    chunkConsumer.accept(lastChunk);
                } else {
                    chunkConsumer.accept(buffer);
                }
            }
        }
    }
}
